/**
 * Created by admin on 14-7-24.
 */
if(typeof (module) !="undefined"){
    module.exports = TextTableTraveller;

    var TextTableObj = require('../obj/TextTableObj');
    var TextTableTd  = require('../obj/TextTableTd');
}




// 先从左向右，再从上向下遍历
// 参数:
//      t:表格
function TextTableTraveller(t){
    // 表
    if(t)
        this.m_table = t;
    else
        this.m_table = null;

    // 当前格子
    this.m_curTd = null;

    // 初始化
    this.init(null);
}

TextTableTraveller.prototype.init = function(c){
    this.clearVisited();

    if(c){
        this.m_curTd = null;
        var n = this.next();
        while(n && n!=c && n.innerId!= c.innerId){
            n = this.next();
        }
        // 设置当前格子
        this.m_curTd = n;
    }else{
        // 设置当前格子
        this.m_curTd = null;
    }
}
TextTableTraveller.prototype.clearVisited = function(){
    this.downTravel (function(td){
        td.visited = false;
    }, function(td){});
}
TextTableTraveller.prototype.print = function(){
    var rowStr = "";
    this.downTravel = function(td){
        rowStr +=  ("("+td.innerId+") ");
        rowStr +="left:[";
        for(var i=0; i<td.left.length; i++){
            rowStr +=(i>0?",":"");
            if(typeof(td.left[i])==undefined || td.left[i] ==null ){
                rowStr += "ERROR_ID";
                alert("error","textTable error");
            }else
                rowStr += td.left[i].innerId;
        }
        rowStr +="]";
        rowStr +="top:[";
        for(var i=0; i<td.top.length; i++){
            rowStr +=(i>0?",":"");
            if(typeof(td.top[i])==undefined || td.top[i] ==null ){
                rowStr += "ERROR_ID";
                alert("error","textTable error");
            }else
                rowStr += td.top[i].innerId;
        }
        rowStr +="]";
        rowStr +="right:[";
        for(var i=0; i<td.right.length; i++){
            rowStr +=(i>0?",":"");
            if(typeof(td.right[i])==undefined || td.right[i] ==null ){
                rowStr += "ERROR_ID";
                alert("error","textTable error");
            }else
                rowStr += td.right[i].innerId;
        }
        rowStr +="]";
        rowStr +="bottom:[";
        for(var i=0; i<td.bottom.length; i++){
            rowStr +=(i>0?",":"");
            if(typeof(td.bottom[i])==undefined || td.bottom[i] ==null ){
                rowStr += "ERROR_ID";
                alert("error","textTable error");
            }else
                rowStr += td.bottom[i].innerId;
        }
        rowStr +="]";
        rowStr +="----"
    }
}
// 特殊遍历：先收集第一列 的所有行，然年后从每行开始向右遍历（采用该方法可能会有部分td被重复访问）
// 注意：这种遍历不修改visited
// 参数：
//		callback：每个元素的处理函数
//		rowEndCallback：第一列的某一行遍历完成后的回调函数

TextTableTraveller.prototype.downTravel = function(callback,rowEndCallback){
    // 先收集第一列 的所有行，然年后从每行开始向右遍历
    var firstCol = new Array();
    var down = this.m_table.leftTop;
    while(down){
        firstCol.push(down);
        if(down.bottom!=null && down.bottom.length>0){
            down = down.bottom[0];
        }else{
            break;
        }
    }
    for(var i=0;i<firstCol.length;i++){
        var row =  firstCol[i];
        if(callback!=null){
            this.rightTravel(row,callback);
        }
        rowEndCallback(row);
    }
}
// 访问某个节点的所有右侧
// 向右优先，再向下
// 注意：这种遍历不修改visited
// 参数：
//		td：起始节点
//		callback: 每个节点的回调
TextTableTraveller.prototype.rightTravel = function(td,callback){
    callback(td);

    for(var i=0;i<td.right.length;i++){
        this.rightTravel(td.right[i],callback);
    }
}
// 访问上一个
// 当到达最左侧时，会访问上一行的末尾
TextTableTraveller.prototype.prev = function(){
    if(this.m_curTd == null)	return null;
    // 设置当前td的visited标记为false
    this.m_curTd.visited = false;

    // 如果是开头，则上一个节点为null
    if(this.m_curTd == this.m_table.leftTop)	{
        this.m_curTd = null;	// 清空当前节点
        return null; // 返回空
    }

    // 找到当前td的上一个，返回
    if(this.m_curTd.left !=null && this.m_curTd.left.length !=0){
        // 如果左侧存在，在返回左侧最下面一个为visited状态的节点
        for(var i=this.m_curTd.left.length-1; i>=0; i--){
            if(this.m_curTd.left[i].visited){
                return this.m_curTd.left[i];
            }
        }
    }else{
        // 如果左侧不存在，则返回上一行的末尾的节点
        if(this.m_curTd.top && this.m_curTd.top.length>0){
            var topRowEnd = null; // 上一行的末尾
            // 从当前节点的上方的节点开始，向右遍历（向右优先，向下次之）
            this.rightTravel(this.m_curTd.top[0], function(td){
                if(td.visited)
                    topRowEnd = td;
            });
            if(topRowEnd){
                return topRowEnd;
            }
        }
    }
 return null;
}
// 访问下一个
// 当到达最右侧时，会访问下一行的开头
// 每访问一个，就设置其visited标记为true
TextTableTraveller.prototype.next = function(){
    // 访问首个
    if(this.m_curTd == null){
        this.m_curTd = this.m_table.leftTop;
        if(this.m_curTd==null)
            return null;

        this.m_curTd.visited = true;
        return this.m_curTd;
    }
    // 向右访问
    if(this.m_curTd.right==null || this.m_curTd.right.length==0){
        // 向右到头,就回退，再次访问
        // 找到left中最后一个visited（就是当前自己的父）
        for(var i=this.m_curTd.left.length-1; i>=0; i--){
            if(this.m_curTd.left[i].visited){
                this.m_curTd = this.m_curTd.left[i];
                return this.next();
            }
        }
    }else{
        // 找到右边
        for(var i=0; i<this.m_curTd.right.length; i++){
            if(!this.m_curTd.right[i].visited){
                this.m_curTd = this.m_curTd.right[i];
                this.m_curTd.visited = true;
                return this.m_curTd;
            }
        }
        // 如果右边都被访问过，则回退到父,再次访问
        // 找到left中最后一个visited（就是当前自己的父）
        for(var i=this.m_curTd.left.length-1; i>=0; i--){
            if(this.m_curTd.left[i].visited){
                this.m_curTd = this.m_curTd.left[i];
                return this.next();
            }
        }
    }
    // 向下访问
    if(this.m_curTd.bottom!=null && this.m_curTd.bottom.length>0){
        this.m_curTd = this.m_curTd.bottom[0];
        this.m_curTd.visited = true;
        return this.m_curTd;
    }
    return null;
}

TextTableTraveller.prototype.between = function(start,end){
    var ret = new Array();
    var start = new TextTableTd();
    var end = new TextTableTd();
    var startX = (start.x<end.x)?start.x: end.x;
    var startY = (start.y<end.y)?start.y: end.y;
    var endX = (end.x+end.w)>(start.x+start.w)?(end.x+end.w):(start.x+start.w);
    var endY = (end.y+end.h)>(start.y+start.h)?(end.y+end.h):(start.y+start.h);

    var traveller = new TextTableTraveller(this.m_table);
    var next= traveller.next();
    while(next){
        var td= next;
        if(td.x>=startX && td.y>=startY && (td.x+td.w)<=endX &&(td.y+td.h)<=endY){
            ret.push(td);
        }
        next = traveller.next();
    }
    return ret;
}
